package com.byt.framlib.basemvp.network;

import android.text.TextUtils;

import com.byt.framlib.baseapp.BaseApplication;
import com.byt.framlib.basemvp.ApiConfig;
import com.byt.framlib.basemvp.interceptor.RequestHeaderIntercept;
import com.byt.framlib.commonutils.LogUtils;
import com.byt.framlib.commonutils.NetWorkUtils;
import com.byt.framlib.commonutils.rsa.RasUtils;
import com.google.gson.Gson;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import okhttp3.CacheControl;
import okhttp3.ConnectionPool;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * 类名称：  HttpUtil
 * 创建者：  钟文浩
 * 创建时间：2017/10/25
 * 邮箱：    m13421029930@163.com
 * 类描述：  HTTP请求工具类
 */
public class HttpUtil {

    private OkHttpClient mHttpClient;
    private static Set<String> encryptkeys; // 加密识别
    private static String PUBLIC_KEY_VALUE = "<RSAKeyValue><Modulus>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3//sR2tXw0wrC2DySx8vNGlqt3Y7ldU9+LBLI6e1KS5lfc5jlTGF7KBTSkCHBM3ouEHWqp1ZJ85iJe59aF5gIB2klBd6h4wrbbHA2XE1sq21ykja/Gqx7/IRia3zQfxGv/qEkyGOx+XALVoOlZqDwh76o2n1vP1D+tD3amHsK7QIDAQAB</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
//    public static PublicKey PUBLICKEY = RsaHelper.decodePublicKeyFromXml(PUBLIC_KEY_VALUE);

    static {
        encryptkeys = new HashSet<String>();
    }


    /**
     * 通过拦截器设置请求头
     *
     * @return 返回带请求头以及签名的client
     */
    private OkHttpClient genericClient() throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
        OkHttpClient.Builder mbuild = new OkHttpClient.Builder()
                .addInterceptor(getHttpLoggingInterceptor())                            //添加请求协议头
                .addInterceptor(RequestHeaderIntercept.getInstance())            //添加请求协议头
//                .addInterceptor(getAddBase64Interceptor())                               // 添加加密参数
                .connectTimeout(ApiConfig.Host.DEFAULT_TIME_OUT, TimeUnit.SECONDS)      //设置连接超时
                .readTimeout(ApiConfig.Host.DEFAULT_TIME_READ, TimeUnit.SECONDS)        //设置读超时
                .writeTimeout(ApiConfig.Host.DEFAULT_TIME_WRITE, TimeUnit.SECONDS)      //设置写超时
                .retryOnConnectionFailure(true)                                         //是否自动重连
                .connectionPool(new ConnectionPool());                                   //链接线程池
        mHttpClient = mbuild.build();//构建OkHttpClient对象
        return mHttpClient;
    }

    /**
     * 日志输出
     * 自行判定是否添加
     *
     * @return
     */
    private HttpLoggingInterceptor getHttpLoggingInterceptor() {
        //日志显示级别
        HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.BODY;
        //新建log拦截器
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(message -> {
            LogUtils.loge(message);
        });
        loggingInterceptor.setLevel(level);
        return loggingInterceptor;
    }

    private Interceptor getAddBase64Interceptor() {
        Interceptor mInterceptor = chain -> {
            Request original = chain.request();
            //请求定制：添加请求头
            Request.Builder requestBuilder = original.newBuilder();
            //请求体定制：统一添加token参数
            if (original.body() instanceof FormBody) {
                FormBody.Builder newFormBody = new FormBody.Builder();
                FormBody oidFormBody = (FormBody) original.body();
                for (int i = 0; i < oidFormBody.size(); i++) {
                    String val = oidFormBody.encodedValue(i);
                    if (encryptkeys.contains(oidFormBody.encodedName(i))) {
                        // 如果里面有加密的参数，则对这个参数进行加密，再加入
                        if (TextUtils.isEmpty(oidFormBody.encodedName(i))) {
                            val = "0";
                        }
                        val = RasUtils.encryptByPublic(val);
                    }
                    newFormBody.addEncoded(oidFormBody.encodedName(i), val);
                }
                requestBuilder.method(original.method(), newFormBody.build());
            }
            Request request = requestBuilder.build();
            return chain.proceed(request);
        };
        return mInterceptor;
    }


    /**
     * 网络缓存数据过滤，没网就使用缓存，有网就加载最新数据
     */
    Interceptor baseCasheInterceptor = new Interceptor() {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            if (!NetWorkUtils.IsNetWorkEnable(BaseApplication.getAppContext()) ||
                    (NetWorkUtils.getNetworkClass(BaseApplication.getAppContext()) == 1)) { // 无网络或者是2G是需要缓存的
                /**
                 * 离线缓存控制， 总的缓存时间 = 在线缓存时间 + 设置离线缓存时间
                 */
                int maxStale = 60 * 60 * 24 * 7; // 保存一周数据
                CacheControl tempCacheControl = new CacheControl.Builder()
                        .onlyIfCached()
                        .maxStale(maxStale, TimeUnit.SECONDS)
                        .build();
                request = request.newBuilder()
                        .cacheControl(tempCacheControl)
                        .build();
            }
            return chain.proceed(request);
        }
    };

    public void closeOkHttpClient() {
        if (mHttpClient != null) {
            try {
                mHttpClient.dispatcher().executorService().shutdown();   //清除并关闭线程池
                mHttpClient.connectionPool().evictAll();                 //清除并关闭连接池
                mHttpClient.cache().close();                             //清除cache
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @return 返回Retrofit对象
     */
    public Retrofit getRetrofitInstance() throws Exception {
        return new Retrofit.Builder()
                .baseUrl(ApiConfig.RELEASE_SERVER_DOMAIN)
                .addConverterFactory(GsonConverterFactory.create(new Gson()))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(ScalarsConverterFactory.create())
                .client(genericClient())
                .build();
    }
}